package com.mfhcd.facepay.service;

import android.Manifest;
import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.mfhcd.facepay.model.Location;
import com.mfhcd.facepay.utils.LogUtil;
import com.tbruyelle.rxpermissions2.RxPermissions;

/**
 * 集成百度、高德的定位服务
 *
 * @author Eiozzgh
 * @author xiaoxiaozrsh@gmail.com
 */
public class LocationService {
    private static final String TAG = "LocationService";
    public static final int LOCATION_ALL = 0;  // 同时使用
    public static final int LOCATION_AMAP = 1; // 高德定位
    public static final int LOCATION_BMAP = 2; // 百度定位
    public static final int DEF_RETRY = 3; // 默认重试次数
    public static final boolean SHOW_PROGRESS = true; // 默认显示定位等待框
    private AppCompatActivity mContext;
    private LocationCallback mCallback;
    private int mCurrentLocation; // 当前正在使用的定位类型
    private int mRetry; //重试次数
    private boolean mShowProgress;
    private AMapLocationClient mAMap;


//    mLocationService = new LocationService(this, new LocationService.LocationCallback() {
//        @Override
//        public void onLocationSuccess(Location location) {
//        }
//
//        @Override
//        public void onLocationFailure(String msg) {
//        }
//    });
//    mLocationService.startLocation(LocationService.LOCATION_ALL);

    public LocationService(AppCompatActivity context, LocationCallback callback) {
        mContext = context;
        mCallback = callback;
        initAMap();
        // initBMap();
    }

    public void startLocation(int locationType) {
        startLocation(locationType, DEF_RETRY, SHOW_PROGRESS);
    }

    /**
     * 开始定位，定位切换逻辑。
     * - 选择ALL
     * -- 先走高德，3次失败后切换到百度
     * -- 百度
     * - 选择一个
     * -- 重试3次结束
     */
    @SuppressLint("CheckResult")
    public void startLocation(int locationType, int retry, boolean showProgress) {
        mCurrentLocation = locationType;
        mRetry = retry;
        mShowProgress = showProgress;
        // 动态申请权限
        RxPermissions rxPermissions = new RxPermissions(mContext);
        rxPermissions.request(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(granted -> {
            if (!granted) {
                // TODO 权限拒绝，弹框提示打开
                Toast.makeText(mContext, "没有定位权限", Toast.LENGTH_SHORT).show();
            } else {
                // CheckUtils.resetLoginCountDownTimer();
                switch (mCurrentLocation) {
                    case LOCATION_ALL:
                    case LOCATION_AMAP:
                        mAMap.startLocation();
                        break;
                    case LOCATION_BMAP:
                        break;
                    default:
                        break;
                }
            }
        });
    }

    private void initAMap() {
        // 初始化定位
        mAMap = new AMapLocationClient(mContext);
        // 设置定位回调监听，这里要实现AMapLocationListener接口，AMapLocationListener接口只有onLocationChanged方法可以实现，用于接收异步返回的定位结果，参数是AMapLocation类型。
        mAMap.setLocationListener(new AMapListener());
        // 初始化定位参数
        AMapLocationClientOption option = new AMapLocationClientOption();
        // 设置定位模式为Hight_Accuracy高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
        option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        // 设置是否返回地址信息（默认返回地址信息）
        option.setNeedAddress(true);
        // 设置是否只定位一次,默认为false
        option.setOnceLocation(true);
        // 设置定位间隔,单位毫秒,默认为2000ms
        option.setInterval(1000);
        // 设置是否开启缓存
        option.setLocationCacheEnable(true);
        // 给定位客户端对象设置定位参数
        mAMap.setLocationOption(option);
    }


    private void handleLocation(boolean success, Location location, String msg) {
        if (success) {
            // 省市区任意一项为空，切换定位
            if (TextUtils.isEmpty(location.getProvince()) || TextUtils.isEmpty(location.getCity()) || TextUtils.isEmpty(location.getDistrict())) {
                LogUtil.e(TAG, "定位结果为空");
                if (mCurrentLocation == LOCATION_ALL) {
                } else {
                    LogUtil.d(TAG, "定位结束");
                    mCallback.onLocationFailure("定位结果为空");
                }
            } else { // 定位成功
                mCallback.onLocationSuccess(location);
            }
        } else {
            mRetry--;
            if (mRetry <= 0) {
                if (mCurrentLocation == LOCATION_ALL) {//切换百度
                    mCurrentLocation = LOCATION_BMAP;
                    mRetry = DEF_RETRY;
                } else { //停止定位
                    mCallback.onLocationFailure(msg);
                }
            } else { //继续当前定位
                switch (mCurrentLocation) {
                    case LOCATION_ALL:
                    case LOCATION_AMAP:
                        mAMap.startLocation();
                        break;
                    case LOCATION_BMAP:
                        break;
                }
            }
        }
    }

    private class AMapListener implements AMapLocationListener {
        @Override
        public void onLocationChanged(AMapLocation amapLocation) {
            LogUtil.d(TAG, "AMap.onLocationChanged");
            StringBuffer sb = new StringBuffer();
            // ErrorCode等于0代表定位成功，其他的为定位失败，具体的可以参照官网定位错误码说明
            if (amapLocation.getErrorCode() == 0) {
                mAMap.stopLocation();
                //获取定位信息
                Location location = new Location();
                location.setLongitude(amapLocation.getLongitude());
                location.setLatitude(amapLocation.getLatitude());
                location.setProvince(amapLocation.getProvince());
                location.setCity(amapLocation.getCity());
                location.setDistrict(amapLocation.getDistrict());
                location.setStreet(amapLocation.getStreet());
                location.setAddr(amapLocation.getAddress());
                location.setCityCode(amapLocation.getCityCode());
                location.setAreaCode(amapLocation.getAdCode());
                LogUtil.d(TAG, location.toString());
                handleLocation(true, location, null);
            } else { // 定位失败
                LogUtil.e(TAG, "AMap.ErrorCode = " + amapLocation.getErrorCode());
                LogUtil.e(TAG, "AMap.ErrorInfo = " + amapLocation.getErrorInfo());
                LogUtil.e(TAG, "AMap.LocationDetail = " + amapLocation.getLocationDetail());
                handleLocation(false, null, amapLocation.getErrorCode() + "\n" +
                        amapLocation.getErrorInfo() + "\n" +
                        amapLocation.getLocationDetail());
            }
        }
    }


    public interface LocationCallback {
        // 定位成功回调
        void onLocationSuccess(Location location);

        // 定位失败回调，错误码和错误信息已整合。
        void onLocationFailure(String msg);
    }
}
